package com.celesea.auth.role.service;

import com.celesea.auth.menu.service.MenuService;
import com.celesea.auth.role.dao.RoleDao;
import com.celesea.auth.role.entity.Role;
import com.celesea.auth.role.entity.RoleCode;
import com.celesea.auth.role.entity.RolePermission;
import com.celesea.auth.role.entity.RoleUser;
import com.celesea.auth.role.vo.RoleFilter;
import com.celesea.auth.role.vo.RolePermissionVo;
import com.celesea.auth.role.vo.RoleVo;
import com.celesea.framework.entity.BaseEntity;
import com.celesea.framework.entity.BusEntity;
import com.celesea.framework.service.AbstractBaseService;
import com.celesea.framework.util.CollectionKit;
import com.celesea.framework.util.Const;
import com.celesea.framework.util.EnvUtil;
import com.celesea.framework.util.Sort;
import com.celesea.framework.vo.DictionaryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author JackYuan
 * @create 2017-10-26 23:17
 */
@Service
public class RoleServiceImpl extends AbstractBaseService<Role> implements RoleService {

    public static final String SORT = "sort";
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private RoleUserService roleUserService;
    @Autowired
    private RolePermissionService rolePermissionService;
    @Autowired
    private MenuService menuService;

    @Override
    public RoleVo selectById(String id) {
        Role entity = super.selectById(id);
        RoleVo role = new RoleVo(entity);
        List<RoleUser> users = roleUserService.findByRole(id);
        if (CollectionKit.isNotEmpty(users)) {
            role.setUsers(users.stream().map(item ->
                    new DictionaryVo(item.getUserId(), item.getUserName())).collect(Collectors.toList()));
        }
        return role;
    }

    @Override
    public RolePermissionVo selectPermissions(String id) {
        Role entity = super.selectById(id);
        RolePermissionVo permissionVo = new RolePermissionVo(entity);
        List<RolePermission> permissions = rolePermissionService.findByRole(id);
        if (CollectionKit.isNotEmpty(permissions)) {
            permissionVo.setPermissions(
                    permissions.stream().map(item -> item.getPermissionCode()).collect(Collectors.toList())
            );
        }
        permissionVo.setPermissionTrees(menuService.selectPermissions());
        return permissionVo;
    }

    @Override
    public RolePermissionVo updatePermissions(RolePermissionVo rolePermissionVo) {
        rolePermissionService.deleteByRole(rolePermissionVo.getId());
        if (CollectionKit.isNotEmpty(rolePermissionVo.getPermissions())) {
            rolePermissionService.insertList(rolePermissionVo.toPermissionVo());
        }
        return rolePermissionVo;
    }

    @Override
    public RoleVo insert(RoleVo entity) {
        boolean hasAdminSystem = EnvUtil.hasAnyRoles(RoleCode.ADMIN_SYSTEM);
        boolean requireAdminSystem = RoleCode.ADMIN_SYSTEM.equals(entity.getCode())
                || RoleCode.ADMIN_BUS.equals(entity.getCode());
        if (requireAdminSystem) {
            Assert.isTrue(hasAdminSystem, "您没有权限执行当前操作！");
        }
        Assert.isTrue(super.checkUnique(entity.toUnique()),"角色编码重复");
        Role role = super.insert(entity.toEntity());
        entity.setId(role.getId());
        roleUserService.insertByRole(entity);
        return entity;
    }

    @Override
    public RoleVo update(RoleVo entity) {
        Role role = super.selectById(entity.getId());
        boolean isAdmin = RoleCode.ADMIN_SYSTEM.equals(role.getCode()) ||
                RoleCode.ADMIN_BUS.equals(role.getCode());
        boolean hasAdminSystem = EnvUtil.hasAnyRoles(RoleCode.ADMIN_SYSTEM);
        boolean requireAdminSystem = RoleCode.ADMIN_SYSTEM.equals(entity.getCode())
                || RoleCode.ADMIN_BUS.equals(entity.getCode());
        if (isAdmin || requireAdminSystem) {
            Assert.isTrue(hasAdminSystem, "您没有权限执行当前操作！");
            Assert.isTrue(requireAdminSystem, "您没有权限执行当前操作！");
        }
        Assert.isTrue(super.checkUnique(entity.toUnique()),"角色编码重复");
        super.update(entity.toEntity());
        roleUserService.deleteByRole(entity.getId());
        roleUserService.insertByRole(entity);
        return entity;
    }

    @Override
    public List<Role> selectList() {
        // TODO 返回权限内的角色
        RoleFilter filter = new RoleFilter();
        filter.setStatusFlag(Const.StatusFlag.ENABLE);
        Sort sort = new Sort();
        sort.setSortField(SORT);
        sort.setSortType(Sort.ASC);
        return super.selectList(filter, sort);
    }

    @Override
    public void disable(String id) {
        Assert.notNull(id, "请选择要停用的数据");
        Role role = new Role();
        role.setId(id);
        role.disable();
        int result = super.updateByExampleSelective(role);
        Assert.isTrue(result > 0, "停用失败！");
    }

    @Override
    public void enable(String id) {
        Assert.notNull(id, "请选择要启用的数据");
        Role role = new Role();
        role.setId(id);
        role.enable();
        int result = super.updateByExampleSelective(role);
        Assert.isTrue(result > 0, "启用失败！");
    }

    @Override
    public int doDelete(String id) {
        checkAdminSystem(id);
        return super.doDelete(id);
    }

    private void checkAdminSystem(String id) {
        Role role = super.selectById(id);
        boolean requireAdminSystem = RoleCode.ADMIN_SYSTEM.equals(role.getCode()) ||
                RoleCode.ADMIN_BUS.equals(role.getCode());
        Assert.isTrue(!requireAdminSystem, "您没有权限执行当前操作！");
    }

    private int updateStatus(String id, Role role) {
        checkAdminSystem(id);
        Example example = new Example(role.getClass());
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andEqualTo(BaseEntity.PK, id).andEqualTo(BusEntity.TALENT_ID, EnvUtil.getTenantId());
        return roleDao.updateByExampleSelective(role, example);
    }
}
